#include <iostream>

using namespace std;


//class Person {
//public:
//    //虚函数--是多态的条件之一
//    virtual Person* BuyTicket() { cout << "Person---买票-全价" << endl; return this; }
//};
////虚函数的的重写/覆盖
////三同：函数名，参数，返回值
////特殊情况：
//// 1、子类虚函数 可以不加virtual（但是如果父类不加virtual，子类加virtual就不会产生多态）
////建议virtual关键字都加上
////2、协变：三同中，返回值可以不同，但是要求返回值必须是一个父子类关系的指针或者引用,也可以是其他子类父类的指针或者引用
//class Student:public Person
//{
//public:
//    //virtual void BuyTicket() { cout << "Student----买票-半价" << endl; }
//
//    virtual Student* BuyTicket() { cout << "Student----买票-半价" << endl; return this; }
//};
//class Soidor :public Person
//{
//public:
//    //virtual void BuyTicket() { cout << "Soidor----买票-优先买票" << endl; }
//    virtual Soidor* BuyTicket() { cout << "Soidor----买票-优先买票" << endl; return this; }
//
//};
////多态的条件：
////1、虚函数的重写
////2、父类的指针或者引用去调用虚函数
//void test(Person& p)
//{
//    p.BuyTicket();
//}
//int main()
//{
//    Person pn;
//    Student st;
//    Soidor sd;
//    test(pn);
//    test(st);
//    test(sd);
//    //普通调用：跟调用对象类型有关
//    //多态调用：（指针或者引用）指向的对象有关
//    return 0;
//}

/// <summary>
/// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// </summary>
//class Person {
//public:
//    virtual ~Person()
//    {
//        cout << " person delete:" << _p << endl;
//        delete[] _p;
//    }
//protected:
//        int* _p = new int[10];
//};
//
//class Student :public Person
//{
//public:
//    virtual ~Student()
//    {
//        cout << " Student delete:" << _s << endl;
//        delete[] _s;
//    }
//protected:
//    int* _s = new int[20];
//};
//int main()
//{
//    //Student s;
//    //Person p;
//    Person* ptr1 = new Person;
//    Person* ptr2 = new Student;
//
//    delete ptr1;
//    delete ptr2;
//    return 0;
//}

////////////////////////////////////////////////////////////////////////
////如果实现一个不能被继承的类
////1、构造私有  c++98
////2、类定义的时候 加final  直接会报错
////overread 检测子类函数是否完成重写
//class A final
//{
//private:
//	A()
//	{}
//};
//
//class B :public A
//{
//
//};



///////////////////////////////////////////////////////////////
////纯虚函数
//class car
//{
//public:
//	virtual void Drive() = 0;
//};
//class BMW :public car
//{
//public:
//	void Drive()
//	{
//		cout << "驾驶乐趣" << endl;
//	}
//
//};
//int main()
//{
//	BMW b;
//	b.Drive();
//
//	return 0;
//}


//class A
//{
//public:
//    //这里func完成了重写，没有规定缺省值相同
//    virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }
//    virtual void test() { func(); }
//};
//
//class B : public A
//{
//public:
//    void func(int val=0) { std::cout << "B->" << val << std::endl; }  //以多态的调用就是b的实现＋父类的接口
//};
//
//int main()
//{
//    B* p = new B;
//    p->test();
//    return 0;
//}



//////////////////////////////////////////////////////////////////
// //多态的原理
//class Base {
//public:
//	virtual void func1() {
//		cout << "Base::func1" << endl;
//	}
//	void func2() {
//		cout << "Base::func2" << endl;
//	}
//private:
//	int _a;
//	char _c;
//};
// class Derive :public Base {
// public:
//	 virtual void func1() { cout << "Derive::func1" << endl; }
//	 void func2() { cout << "Derive::func2" << endl; }
// private:
//	 int _d;
// };
////int main()
////{
////	//cout << sizeof(Base) << endl;  //12 会多一个虚表指针
////	Base b;
////	Derive d;
////	
////	Base* ptr = &b;
////	//普通调用 --编译时/静态  绑定 /决议
////	ptr->func2();
////	ptr = &d;
////	ptr->func2();
////
////
////	//多态调用 --运行时/动态  绑定/决议
////	ptr = &b;
////	ptr->func1();
////	ptr = &d;
////	ptr->func1();
////
////
////	return 0;
////}
//
//
// int main()
// {
//	 int a = 0;
//	 cout << "栈：" << &a << endl;
//	 
//	 int* p1 = new int;
//	 cout << "堆：" << &p1 << endl;
//
//	 const char* str ="hello wrold";
//	 cout << "常量区/代码段：" << (void*)str << endl;
//
//
//
//	 static int c = 1;
//	 cout << "静态区/数据段:" << &c << endl;
//
//	 Base p;
//	 cout << "虚表：" << (void*)*((int*)&p) << endl;
// }



//class Base {
//public:
//	virtual void func1() { cout << "Base::func1" << endl; }
//	virtual void func2() { cout << "Base::func2" << endl; }
//private:
//	int a;
//};
//class Derive :public Base {
//public:
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	virtual void func3() { cout << "Derive::func3" << endl; }
//	void func4() { cout << "Derive::func4" << endl; }
//private:
//	int b;
//};
//
//typedef void(*VFPtr)();   //指针数组  相当于typedef void(*)() VFPtr typedef函数指针 只能向前面那样写
//
//void PrintVFPtr(VFPtr vfptr[],int n)
//{
//	for (int i = 0; i<n; ++i)
//	{
//		printf("[%d]:%p->", i, vfptr[i]);
//		vfptr[i]();  //调用函数 
//	}
//	cout << endl;
//}
//
//int main()
//{
//	Base b;
//	PrintVFPtr((VFPtr*)(*(void**)&b),2);  //既可以打印32位下的虚表地址，也可以打印64位下的虚表地址
//
//	Derive d;
//	PrintVFPtr((VFPtr*)(*(void**)&d),3);
//
//	return 0;
//}

//class Base1 {
//public:
//	virtual void func1() { cout << "Base1::func1" << endl; }
//	virtual void func2() { cout << "Base1::func2" << endl; }
//private:
//	int b1;
//};
//class Base2 {
//public:
//	virtual void func1() { cout << "Base2::func1" << endl; }
//	virtual void func2() { cout << "Base2::func2" << endl; }
//private:
//	int b2;
//};
//class Derive : public Base1, public Base2 {
//public:
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	virtual void func3() { cout << "Derive::func3" << endl; }
//private:
//	int d1;
//};
//
//typedef void(*VFPtr)();
//void PrintVFPtr(VFPtr vfptr[], int n)
//{
//	for (int i = 0; i < n; ++i)
//	{
//		printf("[%d]:%p->", i, vfptr[i]);
//		vfptr[i]();  //调用函数 
//	}
//	cout << endl;
//}
//
//int main()
//{
//	Base1 b1;
//	PrintVFPtr((VFPtr*)(*(void**)&b1), 2);
//
//	Base1 b2;
//	PrintVFPtr((VFPtr*)(*(void**)&b2), 2);
//
//	Derive d;
//	//先打印b1部分的函数
//	PrintVFPtr((VFPtr*)(*(void**)&d), 3);
//	PrintVFPtr((VFPtr*)(*(void**)((char*)&d+sizeof(Base1))), 2);   //注意这里的&d+1是加的sizeof(Derive)大小的位置，所以需要强转为char*类型的
//	Base2* ptr = &d;
//
//	PrintVFPtr((VFPtr*)(*(void**)ptr), 2);
//	return 0;
//}



/// <summary>
/// 虚表指针是在初始化列表进行初始化的，所以构造函数不能是虚函数，但是析构函数最好是写成虚函数
/// </summary>

class A {
public:
	A(char* s) { cout << s << endl; }
	~A() {}
};
class B : public A
{
public:
	B(char* s1, char* s2) :A(s1) { cout << s2 << endl; }
};
class C : public A
{
public:
	C(char* s1, char* s2) :A(s1) { cout << s2 << endl; }
};
class D :public C, public B
{
public:
	D(char* s1, char* s2, char* s3, char* s4)    //这里是菱形虚拟继承，需要按照继承顺序走，同时需要按照声明顺序所以是ABCD
		:B(s1, s2)                               //如果是普通继承，则是按照继承顺序走，b在前就是abacd  c在前就是acabd
		, C(s1, s3)
	{
		cout << s4 << endl;
	}
};
int main() {
	char a[]="class A";
	char b[] = "class B";
	char c[] = "class C";
	char d[] = "class D";

	D* p = new D(a,b,c,d);
	delete p;
	return 0;
}




